﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CalcSharp.Core.PackageMan;
using System.Drawing;
using mkpack.Properties;
using CalcSharp.Core.IO;
using System.IO;


namespace mkpack
{
    class options
    {
        public string srcdir;
        public string iconname;
        public string name;
        public string description;
        public string output;
        public bool reqhelp;
        public string v;
        public string license;
        public List<string> reqs;
        public options()
        {
            this.reqs = new List<string>();
            this.v = null;
        }
        public static bool isempty(options o)
        {
            if (string.IsNullOrEmpty(o.srcdir) && string.IsNullOrEmpty(o.v) && string.IsNullOrEmpty(o.iconname) && string.IsNullOrEmpty(o.description) && string.IsNullOrEmpty(o.name) && string.IsNullOrEmpty(o.output)) return true;
            else return false;
        }
        public static bool hasreqs(options o)
        {
            if (string.IsNullOrEmpty(o.srcdir) || string.IsNullOrEmpty(o.description) || string.IsNullOrEmpty(o.name) || string.IsNullOrEmpty(o.v)) return false;
            else return true;
        }
    }

    class Program
    {
        static void help()
        {
            Console.WriteLine("-------------------------------------------------------------------------------");
            Console.WriteLine("mkpack - Calc# package builder utility");
            Console.WriteLine("-------------------------------------------------------------------------------");
            Console.WriteLine("Usage: -n <name> -d <description> -s <source> -i <image> -o <output>");
            Console.WriteLine("  -n (--name):        Package name *");
            Console.WriteLine("  -d (--description): Package Description *");
            Console.WriteLine("  -s (--source):      Source directory *");
            Console.WriteLine("  -v (--version):     Package version *");
            Console.WriteLine("  -r (--require):     Add a required package");
            Console.WriteLine("  -i (--img):         Package icon file name");
            Console.WriteLine("  -l (--license):     Packgage license file. (txt format)");
            Console.WriteLine("  -o (--output):      Output Directory");
            Console.WriteLine("\nParameters marked with a * are required!");
            Console.Write("\n\nPress a key to exit....");
            Console.ReadKey();
        }

        static PackageVersion parseversion(string input)
        {
            PackageVersion v = new PackageVersion();
            string[] pars = input.Split('.');
            if (pars.Length != 4) return null;
            v.Major = Convert.ToByte(pars[0]);
            v.Minor = Convert.ToByte(pars[1]);
            v.Build = Convert.ToByte(pars[2]);
            v.Revision = Convert.ToByte(pars[3]);
            return v;
        }

        static options parsecmdline(string[] cmdline)
        {
            options retval = new options();
            for (int i = 0; i < cmdline.Length; i++)
            {
                switch (cmdline[i])
                {
                    case "-n":
                    case "--name":
                        retval.name = cmdline[i + 1].Replace(" ", "_");
                        break;
                    case "-d":
                    case "--description":
                        retval.description = cmdline[i + 1];
                        break;
                    case "-s":
                    case "--source":
                        retval.srcdir = cmdline[i + 1];
                        break;
                    case "-r":
                    case "--require":
                        retval.reqs.Add(cmdline[i + 1]);
                        break;
                    case "-i":
                    case "--img":
                        retval.iconname = cmdline[i + 1];
                        break;
                    case "-v":
                    case "--version":
                        retval.v = cmdline[i + 1];
                        break;
                    case "-h":
                    case "--help":
                        retval.reqhelp = true;
                        break;
                    case "-l":
                    case "--license":
                        retval.license = File.ReadAllText(cmdline[i + 1]);
                        break;
                    case "-o":
                    case "--output":
                        retval.output = cmdline[i + 1];
                        break;
                }
            }
            return retval;
        }

        static void Main(string[] args)
        {
            Package P = new Package();
            options programoptions;
            int i;
            try
            {
                programoptions = Program.parsecmdline(args);
                if (options.isempty(programoptions) || programoptions.reqhelp || !options.hasreqs(programoptions)) Program.help();
                else
                {
                    P.name = programoptions.name;
                    P.Description = programoptions.description;
                    P.version = parseversion(programoptions.v);
                    if (!string.IsNullOrEmpty(programoptions.iconname)) P.icon = new base64png(programoptions.iconname);
                    else P.icon = new base64png(Properties.Resources.defaultico);
                    if (programoptions.reqs.Count > 0)
                    {
                        List<DependentPackage> dpds = new List<DependentPackage>();
                        string[] pars;
                        for (i = 0; i < programoptions.reqs.Count; i++)
                        {
                            pars = programoptions.reqs[i].Split(' ');
                            DependentPackage t = new DependentPackage();
                            t.name = pars[0];
                            t.version = parseversion(pars[1]);
                            dpds.Add(t);
                        }
                        P.requires = dpds.ToArray();
                    }
                    string[] entrys = FileHelper.GetAllFileNames(programoptions.srcdir, "*.*");
                    P.files = new string[entrys.Length];
                    P.license = programoptions.license;
                    for (i = 0; i < entrys.Length; i++)
                    {
                        P.files[i] = entrys[i].Replace(programoptions.srcdir+"\\", "");
                    }
                    Console.WriteLine("Creating Package: " + programoptions.name + ".cspack");
                    Console.WriteLine("Please Wait...");
                    if (string.IsNullOrEmpty(programoptions.output)) ZipPack.Pack(programoptions.srcdir, programoptions.name + ".cspack", P);
                    else ZipPack.Pack(programoptions.srcdir, programoptions.output + "\\" + programoptions.name + ".cspack", P);
                }
            }
            catch (IndexOutOfRangeException)
            {
                Program.help();
            }
        }
    }
}
